// 知识点1：对于一个参数包，我们还可以对其进行参数扩展，即将一个包分解为其构成元素，我们通过在模式的右边放一个省略号...来出发扩展操作，见53题中print函数中的return语句

// 知识点2：我们还可以对作为参数的函数进行扩展，但注意省略号的位置，不是对函数参数的扩展
#include <iostream>
#include <sstream>
#include <string>

template <typename T>
std::string debug_rep(const T &t);
template <typename T>
std::string debug_rep(T *p);

std::string debug_rep(const std::string &s);
std::string debug_rep(char *p);
std::string debug_rep(const char *p);

template <typename T>
std::string debug_rep(const T &s) {
  std::ostringstream ret;
  ret << s;
  return ret.str();
}
template <typename T>
std::string debug_rep(T *p) {
  std::ostringstream ret;
  std::cout << "point:" << std::endl;
  if (p)
    ret << " " << debug_rep(*p);
  else
    ret << "point is NULL!";
  return ret.str();
}
template <typename T>
std::ostream &print(std::ostream &os, const T &t) {
  return os << t;
}
template <typename T, typename... Args>
std::ostream &print(std::ostream &os, const T &t, const Args &... args) {
  os << t << ", ";
  return print(os, args...);
}
std::string debug_rep(const std::string &s) { return '"' + s + '"'; }
std::string debug_rep(char *p) { return debug_rep(std::string(p)); }

std::string debug_rep(const char *p) { return debug_rep(std::string(p)); }
template <typename... Args>
std::ostream &errorMsg(std::ostream &os, const Args... args) {
  return print(os, debug_rep(args)...);
}

int main() {
  using namespace std;
  string str = "c++";
  errorMsg(cout, str, "primer", 4, 8.6, '5');

  system("pause");
  return 0;
}